package com.corpgovernment.travelstandard.impl;

import cn.hutool.core.text.StrBuilder;
import com.corpgovernment.api.applytrip.apply.sync.StandardReserveTypeSyncRequest;
import com.corpgovernment.api.applytrip.soa.response.QueryApplyTripStandardResponse;
import com.corpgovernment.api.flightintl.dto.enums.CabinFlag;
import com.corpgovernment.api.organization.model.post.PostVo;
import com.corpgovernment.api.travelstandard.enums.*;
import com.corpgovernment.api.travelstandard.service.IMbTravelstandIntlFlightService;
import com.corpgovernment.api.travelstandard.vo.*;
import com.corpgovernment.api.travelstandard.vo.intlflight.ClassSpace;
import com.corpgovernment.api.travelstandard.vo.intlflight.IntlFlightManageVo;
import com.corpgovernment.api.travelstandard.vo.intlflight.MbTravelstandIntlFlightVo;
import com.corpgovernment.api.travelstandard.vo.operate.FlightOperateLogVo;
import com.corpgovernment.api.travelstandard.vo.operate.IntlFlightOperateLogVo;
import com.corpgovernment.api.travelstandard.vo.request.IntlFlightShowRequest;
import com.corpgovernment.api.travelstandard.vo.response.FlightIntlTravelStandardShowTextResponse;
import com.corpgovernment.api.travelstandard.vo.response.IntlFlightShowResponse;
import com.corpgovernment.client.ManagementClientUtil;
import com.corpgovernment.common.base.BaseRequestVO.UserInfo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.currency.CurrencyConversionUtil;
import com.corpgovernment.common.currency.bo.CurrencyExchangeBO;
import com.corpgovernment.common.currency.bo.CurrencyExchangeBO;
import com.corpgovernment.common.enums.ExceptionCodeEnum;
import com.corpgovernment.common.utils.DateUtil;
import com.corpgovernment.common.utils.ListUtils;
import com.corpgovernment.common.utils.ObjectUtils;
import com.corpgovernment.common.utils.PageUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.constant.CommonConst;
import com.corpgovernment.common.utils.*;
import com.corpgovernment.constants.TravelStandardOwnerTypeEnum;
import com.corpgovernment.dto.travelstandard.request.GetTravelStandardByTokenRequest;
import com.corpgovernment.dto.travelstandard.response.TravelStandardResponse;
import com.corpgovernment.dto.travelstandard.response.TravelStandardRuleVO;
import com.corpgovernment.dto.travelstandard.response.rule.*;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.dataloader.ApplyTripClientLoader;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.supplier.constant.CommonConstant;
import com.corpgovernment.travelstandard.entity.db.MbTravelstandIntlFlight;
import com.corpgovernment.travelstandard.entity.db.TravelStandardPost;
import com.corpgovernment.travelstandard.enums.TravelUnLimitedTypeEnum;
import com.corpgovernment.travelstandard.mapper.MbTravelstandIntlFlightMapper;
import com.corpgovernment.travelstandard.utils.BeanConverUtil;
import com.ctrip.corp.obt.generic.exception.CommonException;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.context.PageContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j



@Service
public class MbTravelstandIntlFlightService extends TravelStandardBaseService implements IMbTravelstandIntlFlightService {

    private final static String[] INTL_FLIGHT_RC_TEMPS = {"intlFlightRcFcTemp", "intlFlightRcFlTemp",
            "intlFlightRcFaTemp", "intlFlightRcFtTemp", "intlFlightRcFpTemp", "intlFlightRcAmTemp"};

    private final static String[] WEEK = {"每天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};

    @Autowired
    private MbTravelstandIntlFlightMapper mbTravelstandIntlFlightMapper;
    @Autowired
    private MbTravelstandReasonCodeService travelstandReasonCodeService;
    @Autowired
    private TravelStandardPostService travelStandardPostService;
    @Autowired
    private TravelStandardPostService standPostService;
    @Autowired
    private ApplyTripClientLoader applyTripClientLoader;
    @Autowired
    private MbTravelstandFlightCabinService standFlightCabinService;

    @Autowired
    private MbTravelstandIntlFlightTimeService mbTravelstandIntlFlightTimeService;
    @Autowired
    private MbTravelstandCurrencyExchangeService mbTravelstandCurrencyExchangeService;
    @Autowired
    private ManagementClientUtil managementClientUtil;
    /**
     * 默认币种符号为人民币
     */
    private static final String CNY_CODE = "CNY";

    /**
     * 人民币符号
     */
    private static final Character CNY_SYMBOL = '¥';
    @Override
    public void insert(MbTravelstandIntlFlightVo model) {
        mbTravelstandIntlFlightMapper.insertSelective(ObjectUtils.copyProperties(model, MbTravelstandIntlFlight.class));
    }

    @Override
    public int delete(Long id) {
        return mbTravelstandIntlFlightMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int update(MbTravelstandIntlFlightVo model) {
        return mbTravelstandIntlFlightMapper.updateByPrimaryKeySelective(ObjectUtils.copyProperties(model, MbTravelstandIntlFlight.class));
    }

    @Override
    public MbTravelstandIntlFlightVo get(Long id) {
        return ObjectUtils.copyProperties(mbTravelstandIntlFlightMapper.selectByPrimaryKey(id), MbTravelstandIntlFlightVo.class);
    }

    @Override
    public Page page(MbTravelstandIntlFlightVo model) {
        MbTravelstandIntlFlight param = ObjectUtils.copyProperties(model, MbTravelstandIntlFlight.class);
        PageContext.startPage(model.getPageNum(), model.getPageSize());
        List<MbTravelstandIntlFlight> list = mbTravelstandIntlFlightMapper.list(param);
        return PageUtils.optPageBy(list, MbTravelstandIntlFlightVo.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertIntlFlightTravelStandard(MbTravelstandIntlFlightVo model) {
        MbTravelstandIntlFlight mbTravelstandIntlFlight = ObjectUtils.copyProperties(model, MbTravelstandIntlFlight.class);
        mbTravelstandIntlFlight.setDatachangeCreatetime(new Date());
        mbTravelstandIntlFlight.setDatachangeLasttime(new Date());
        mbTravelstandIntlFlightMapper.insert(mbTravelstandIntlFlight);
        model.setId(mbTravelstandIntlFlight.getId());
        //从apollo获取默认RC并插入
        insertTravelstandReasonCode(INTL_FLIGHT_RC_TEMPS, model.getId());
        //插入默认时间管控
        mbTravelstandIntlFlightTimeService.insert(
                new MbTravelstandIntlFlightTimeVo()
                .setTsIntlFlightId(model.getId())
                .setStartTime(DateUtil.stringToDate("00:00", DateUtil.DF_HM))
                .setEndTime(DateUtil.stringToDate("23:59", DateUtil.DF_HM))
                .setWeek(1));
        insertOperateLog(coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(model));
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateIntlFlightTravelStandardProperty(IntlFlightManageVo intlFlightManageVo) {
        String jobScopeId = intlFlightManageVo.getJobScopeId();
        String id = intlFlightManageVo.getId();
        if (StringUtils.isBlank(id)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_ID_IS_NULL);
        }
        if (StringUtils.isBlank(jobScopeId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.JOB_SCOPEID_IS_NULL);
        }
        String orgId = intlFlightManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        ClassSpace classSpace = intlFlightManageVo.getClassSpace();
        if (classSpace == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.CLASS_DISCOUNT_CONTROL_IS_NULL);
        }
        LowPriceDomAirTicket lowPriceDomAirTicket = intlFlightManageVo.getLowPriceDomAirTicket();
        if (lowPriceDomAirTicket == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.LOW_PRICE_DOMAIR_TICKET_IS_NULL);
        }
        AdvancedBook advancedBook = intlFlightManageVo.getAdvancedBook();
        if (advancedBook == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ADVANCED_BOOK_IS_NULL);
        }
        IntlAmountControlVo amountControlVo = intlFlightManageVo.getAmountControlVo();
        if (amountControlVo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.AMOUNT_CONTROL_IS_NULL);
        }
        //时间管控
        TimeControl timeControl = intlFlightManageVo.getTimeControl();
        if (Objects.isNull(timeControl)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TIME_CONTROL_IS_NULL);
        }
        // 协议价
        ProtocolPriceControl protocolPrice = intlFlightManageVo.getProtocolPriceControl();
        if (Objects.isNull(protocolPrice)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PROTOCOL_PRICE_IS_NULL);
        }
        MbTravelstandIntlFlightVo oriMbTravelstandIntlFlightVo = get(Long.valueOf(id));
        if (oriMbTravelstandIntlFlightVo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_IS_NULL);
        }
        IntlFlightOperateLogVo oriIntlFlightOperateLogVo = coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(oriMbTravelstandIntlFlightVo);
        //可选舱位
        StringBuilder classClass = new StringBuilder("");
        // 可订舱等
        List<com.corpgovernment.api.travelstandard.vo.intlflight.ClassSpace.ClassCheckNew> classCheckNewList
                = classSpace.getClassCheckNewList();
        // 屏蔽舱等
        List<String> ClassShieldedList = classSpace.getClassShieldedList();
        if(CollectionUtils.isNotEmpty(ClassShieldedList) && CollectionUtils.isNotEmpty(classCheckNewList)) {
            for(com.corpgovernment.api.travelstandard.vo.intlflight.ClassSpace.ClassCheckNew classNode : classCheckNewList) {
                for(String ClassShielded :ClassShieldedList){
                    if(StringUtils.endsWithIgnoreCase(classNode.getClassCode(), ClassShielded)) {
                        throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_CLASS_REPEAT);
                    }
                }
            }
        }
        if(CollectionUtils.isNotEmpty(classCheckNewList)) {
            // 新舱等配置
            for (com.corpgovernment.api.travelstandard.vo.intlflight.ClassSpace.ClassCheckNew classNode : classCheckNewList) {
                classClass = new StringBuilder(classNode.getClassCode());
            }
        } else if(CollectionUtils.isNotEmpty(classSpace.getClassCheckList())) {
            List<Node> classNodes = classSpace.getClassCheckList();
            for (Node classNode : classNodes) {
                if (classNode.getIsChecked()) {
                    classClass.append(classNode.getCode());
                }
            }
        }
        //低价国内机票RC检测时间段
        Integer lowpriceTimeOption = null;
        if (StringUtils.isNotBlank(lowPriceDomAirTicket.getLowPriceDomAirTicketTimeOptionsHour()) && StringUtils.isNotBlank(lowPriceDomAirTicket.getLowPriceDomAirTicketTimeOptionsMinutes())) {
            lowpriceTimeOption = Integer.parseInt(lowPriceDomAirTicket.getLowPriceDomAirTicketTimeOptionsHour()) * 60 + Integer.parseInt(lowPriceDomAirTicket.getLowPriceDomAirTicketTimeOptionsMinutes());
        }
        // 低价浮动类型 A-固定金额浮动 B-固定比例浮动
        if (!FlightSwitchEnum.LowPriceFloatTypeSwitch.B.getCode().equals(lowPriceDomAirTicket.getLowPriceFloatType())) {
            lowPriceDomAirTicket.setLowPriceFloatType(FlightSwitchEnum.LowPriceFloatTypeSwitch.A.getCode());
        }
        // 低价浮动金额数
        Integer lowPriceFloatAmount = null;
        if(StringUtils.isNotBlank(lowPriceDomAirTicket.getLowPriceFloatAmount())) {
            lowPriceFloatAmount = Integer.parseInt(lowPriceDomAirTicket.getLowPriceFloatAmount());
        }
        // 低价浮动比例数
        Integer lowPriceFloatNum = null;
        if(StringUtils.isNotBlank(lowPriceDomAirTicket.getLowPriceFloatNum())) {
            lowPriceFloatNum = Integer.parseInt(lowPriceDomAirTicket.getLowPriceFloatNum());
        }
        // 机场比价赋默认值
        if (!CommonConst.TRUE.equals(lowPriceDomAirTicket.getAirportComparePrice())){
            lowPriceDomAirTicket.setAirportComparePrice(CommonConst.FALSE);
        }
        MbTravelstandIntlFlightVo mbTravelstandIntlFlightVo = new MbTravelstandIntlFlightVo(
                Long.valueOf(id),
                orgId,
                intlFlightManageVo.getTitle(),
                classSpace.getStatus(),
                classClass.toString(),
                classSpace.getClassRcSet(),
                lowPriceDomAirTicket.getStatus(),
                lowpriceTimeOption,
                DateUtil.stringToDate(lowPriceDomAirTicket.getLowPriceTimeStart(), DateUtil.DF_HM),
                DateUtil.stringToDate(lowPriceDomAirTicket.getLowPriceTimeEnd(), DateUtil.DF_HM),
                lowPriceDomAirTicket.getLowPriceRcSet(),
                advancedBook.getStatus(),
                advancedBook.getAdvancedBookDays(),
                advancedBook.getBookRcSet()
        );
        mbTravelstandIntlFlightVo.setProductSwitch(intlFlightManageVo.getProductSwitch());
        mbTravelstandIntlFlightVo.setLowpriceFloatType(lowPriceDomAirTicket.getLowPriceFloatType());
        mbTravelstandIntlFlightVo.setLowpriceFloatAmount(lowPriceFloatAmount);
        mbTravelstandIntlFlightVo.setLowpriceFloatNum(lowPriceFloatNum);
        mbTravelstandIntlFlightVo.setAirportComparePrice(lowPriceDomAirTicket.getAirportComparePrice());
        mbTravelstandIntlFlightVo.setAmountControlSwitch(amountControlVo.getStatus());
        mbTravelstandIntlFlightVo.setAmountControlNum(amountControlVo.getAmountControlNum());
        mbTravelstandIntlFlightVo.setAmountControlCurrency(amountControlVo.getAmountControlCurrency());
        mbTravelstandIntlFlightVo.setAmountControlType(amountControlVo.getAmountRcSet());
        // 管控时间
        mbTravelstandIntlFlightVo.setTimeSwitch(timeControl.getStatus());
        mbTravelstandIntlFlightVo.setTimeChooseType(timeControl.getTimeChooseType());
        mbTravelstandIntlFlightVo.setTimeControlType(timeControl.getTimeRcSet());
        //协议价管控
        mbTravelstandIntlFlightVo.setProtocolPriceSwitch(protocolPrice.getStatus());
        mbTravelstandIntlFlightVo.setProtocolPriceControlType(protocolPrice.getProtocolPriceRcSet());
        //更新差标属性
        if (update(mbTravelstandIntlFlightVo) != 1) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_UPDATE_FAILED);
        }
        //更新舱等RC
        RCListVo rcListVoFc = new RCListVo();
        rcListVoFc.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFc.setRcList(classSpace.getClassRcList());
        rcListVoFc.setRcType(ReasonCodeTypeEnum.IFC.getCode());
        rcListVoFc.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFc);
        //更新低价RC
        RCListVo rcListVoFl = new RCListVo();
        rcListVoFl.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFl.setRcList(lowPriceDomAirTicket.getLowPriceRcCheckList());
        rcListVoFl.setRcType(ReasonCodeTypeEnum.IFL.getCode());
        rcListVoFl.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFl);
        //更新提前预订RC
        RCListVo rcListVoFa = new RCListVo();
        rcListVoFa.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFa.setRcList(advancedBook.getBookRcCheckList());
        rcListVoFa.setRcType(ReasonCodeTypeEnum.IFA.getCode());
        rcListVoFa.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFa);
        // 新舱等配置 批量删除旧的配置 批量新增新的配置
        standFlightCabinService.deleteByTsId(mbTravelstandIntlFlightVo.getId(), TravelStandardTypeEnum.IntlFlight.getCode());
        List<MbTravelstandFlightCabinVo> model = new ArrayList<>();
        // 可订舱等
        if(CollectionUtils.isNotEmpty(classCheckNewList)) {
            for(com.corpgovernment.api.travelstandard.vo.intlflight.ClassSpace.ClassCheckNew classCheckNewNode: classCheckNewList) {
                MbTravelstandFlightCabinVo flightCabinVo = new MbTravelstandFlightCabinVo();
                flightCabinVo.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
                flightCabinVo.setTsFlightId(mbTravelstandIntlFlightVo.getId());
                flightCabinVo.setCabinType(CommonConstant.T);
                flightCabinVo.setClassCode(classCheckNewNode.getClassCode());
                flightCabinVo.setFlightDurationType(Optional.ofNullable(classCheckNewNode.getDurationType())
                        .orElse(CommonConstant.F));
                flightCabinVo.setFlightDurationNum(classCheckNewNode.getDurationNum());
                model.add(flightCabinVo);
            }
        }
        // 屏蔽舱等
        if(CollectionUtils.isNotEmpty(ClassShieldedList)) {
            for(String classShielded : ClassShieldedList) {
                MbTravelstandFlightCabinVo flightCabinVo = new MbTravelstandFlightCabinVo();
                flightCabinVo.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
                flightCabinVo.setTsFlightId(mbTravelstandIntlFlightVo.getId());
                flightCabinVo.setCabinType(CommonConstant.F);
                flightCabinVo.setClassCode(classShielded);
                flightCabinVo.setFlightDurationType(CommonConstant.F);
                model.add(flightCabinVo);
            }
        }
        if(CollectionUtils.isNotEmpty(model)) {
            standFlightCabinService.insertList(model);
        }
        //更新金额管控RC
        RCListVo rcListVoFcp = new RCListVo();
        rcListVoFcp.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFcp.setRcList(amountControlVo.getAmountRcCheckList());
        rcListVoFcp.setRcType(ReasonCodeTypeEnum.IAM.getCode());
        rcListVoFcp.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFcp);
        //更新时间RC
        RCListVo rcListVoFt = new RCListVo();
        rcListVoFt.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFt.setRcList(timeControl.getTimeRcCheckList());
        rcListVoFt.setRcType(ReasonCodeTypeEnum.IFT.getCode());
        rcListVoFt.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFt);
        //更新协议价RC
        RCListVo rcListVoFp = new RCListVo();
        rcListVoFp.setId(String.valueOf(mbTravelstandIntlFlightVo.getId()));
        rcListVoFp.setRcList(protocolPrice.getProtocolPriceRcCheckList());
        rcListVoFp.setRcType(ReasonCodeTypeEnum.IFP.getCode());
        rcListVoFp.setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFp);
        //删除时间信息
        mbTravelstandIntlFlightTimeService.deleteByTsId(mbTravelstandIntlFlightVo.getId());
        //循环添加新管控时间信息
        List<MbTravelstandIntlFlightTimeVo> travelstandFlightTimeVos = timeControl.getMbTravelstandIntlFlightTimeVos();
        if (CollectionUtils.isNotEmpty(travelstandFlightTimeVos)){
            for (MbTravelstandIntlFlightTimeVo travelstandFlightTimeVo : travelstandFlightTimeVos) {
                mbTravelstandIntlFlightTimeService.insert(travelstandFlightTimeVo);
            }
        }
        //删除旧职位
        travelStandardPostService.deleteByTsidAndTsType(mbTravelstandIntlFlightVo.getId(), TravelStandardTypeEnum.IntlFlight.getCode());
        //循环添加职位
        String[] jobIds = jobScopeId.split(",");
        for (String jobId : jobIds) {
            TravelStandardPostVo travelStandardPostVo = new TravelStandardPostVo();
            travelStandardPostVo.setPostid(Long.valueOf(jobId));
            travelStandardPostVo.setOrgid(orgId);
            travelStandardPostVo.setTsid(mbTravelstandIntlFlightVo.getId());
            travelStandardPostVo.setTstype(TravelStandardTypeEnum.IntlFlight.getCode());
            travelStandardPostVo.setTsname(mbTravelstandIntlFlightVo.getName());
            travelStandardPostService.insert(travelStandardPostVo);
        }
        updateOperateLog(
                oriIntlFlightOperateLogVo,
                coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(mbTravelstandIntlFlightVo)
        );
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteIntlFlightTravelStandard(Long id) {
        MbTravelstandIntlFlightVo oriMbTravelstandIntlFlightVo = get(id);
        if (oriMbTravelstandIntlFlightVo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_IS_NULL);
        }
        IntlFlightOperateLogVo oriIntlFlightOperateLogVo = coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(oriMbTravelstandIntlFlightVo);
        //删除机票差标
        mbTravelstandIntlFlightMapper.deleteByPrimaryKey(id);
        //删除差标相关职位
        travelStandardPostService.deleteByTsidAndTsType(id, TravelStandardTypeEnum.IntlFlight.getCode());
        //删除差标相关RC
        travelstandReasonCodeService.deleteByTsIdAndTsType(id, TravelStandardTypeEnum.IntlFlight.getCode());
        //删除差标相关舱位信息
        standFlightCabinService.deleteByTsId(id, TravelStandardTypeEnum.IntlFlight.getCode());
        //删除差标相关时间信息
        mbTravelstandIntlFlightTimeService.deleteByTsId(id);
        deleteOperateLog(oriIntlFlightOperateLogVo, new FlightOperateLogVo());
    }

    public void updateStandardName(Long id, String title) {
        MbTravelstandIntlFlightVo oriMbTravelstandIntlFlightVo = get(id);
        if (oriMbTravelstandIntlFlightVo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.TRAVEL_STAND_IS_NULL);
        }
        IntlFlightOperateLogVo oriIntlFlightOperateLogVo = coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(oriMbTravelstandIntlFlightVo);
        update(new MbTravelstandIntlFlightVo() {{
            setId(Long.valueOf(id));
            setName(title);
        }});
        IntlFlightOperateLogVo intlFlightOperateLogVo = ObjectUtils.copyProperties(oriIntlFlightOperateLogVo, IntlFlightOperateLogVo.class);
        intlFlightOperateLogVo.setName(title);
        updateOperateLog(oriIntlFlightOperateLogVo, intlFlightOperateLogVo);
    }

    public List<IntlFlightManageVo> listIntlFlightTravelStandard(MbTravelstandIntlFlightVo model) {
        List<IntlFlightManageVo> intlFlightManageVos = new ArrayList<>();
        List<MbTravelstandIntlFlightVo> mbTravelstandIntlFlightVos = ListUtils.copyList(mbTravelstandIntlFlightMapper.list(ObjectUtils.copyProperties(model, MbTravelstandIntlFlight.class)), MbTravelstandIntlFlightVo.class);
        for (MbTravelstandIntlFlightVo mbTravelstandIntlFlightVo : mbTravelstandIntlFlightVos) {
            //获得差标关联的岗位
            List<TravelStandardPost> travelStandardPosts = travelStandardPostService.list(new TravelStandardPostVo() {{
                setTsid(mbTravelstandIntlFlightVo.getId());
                setTstype(TravelStandardTypeEnum.IntlFlight.getCode());
            }});
            //获得差标关联的RC
            List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                setTsId(mbTravelstandIntlFlightVo.getId());
                setTsType(TravelStandardTypeEnum.IntlFlight.getCode());
            }});
            List<MbTravelstandFlightCabinVo> standFlightCabinVos = standFlightCabinService.list(
                    new MbTravelstandFlightCabinVo().setTsFlightId(mbTravelstandIntlFlightVo.getId())
                            .setTsType(TravelStandardTypeEnum.IntlFlight.getCode()));

            //获得差标关联的时间管控信息
            List<MbTravelstandIntlFlightTimeVo> mbTravelstandIntlFlightTimeVos = mbTravelstandIntlFlightTimeService.list(new MbTravelstandIntlFlightTimeVo().setTsIntlFlightId(mbTravelstandIntlFlightVo.getId()));
            intlFlightManageVos.add(BeanConverUtil.travelstandIntlFlightVoToIntlFlightManageVo(
                    mbTravelstandIntlFlightVo,
                    ListUtils.copyList(travelStandardPosts, TravelStandardPostVo.class),
                    travelstandReasonCodeVos,
                    standFlightCabinVos,
                    mbTravelstandIntlFlightTimeVos
            ));
        }
        return intlFlightManageVos;
    }

    public IntlFlightShowResponse intlFlightShow(String orgId, String uid, Long postId, Long trafficId, String token) {
        if (StringUtils.isNotBlank(token)){
            return flightTravelStandardShowByToken(token);
        }

        QueryApplyTripStandardResponse applyTripStandard = applyTripClientLoader.getFlightApplyTripStandard(trafficId);
        if (applyTripStandard == null) {
            throw new CommonException(OrganizationResponseCodeEnum.TRAVEL_STAND_APPLY_IS_NULL);
        }
        IntlFlightShowResponse intlFlightShowResponse = new IntlFlightShowResponse();
        intlFlightShowResponse.setTitle("国际机票");
        List<RcDetailVo> rcDetailVos = new ArrayList<>();

        if (BooleanUtils.isTrue(applyTripStandard.getEnable())){
            // 出差申请单差标优先
            rcDetailVos.add(buildControlRCDetail("最低价控制"));
            rcDetailVos.add(buildControlRCDetail("提前预订"));
            // 可订舱位不限
            if (TravelUnLimitedTypeEnum.isUnLimitReserve(applyTripStandard.getUnLimitedType())) {
                rcDetailVos.add(buildControlRCDetail("可订舱位"));
            } else {
                String content = applyTripStandard.getStandardReserve().getReserveTypeList().stream()
                    .map(StandardReserveTypeSyncRequest::getReserveCode)
                    .map(CabinFlag::valueOf)
                    .map(CabinFlag::getDisplayName)
                    .collect(Collectors.joining("、"));
                String controlMode = ControlTypeEnum.getEnumByCode(applyTripStandard.getStandardReserve().getControlType()).getName();
                RcDetailVo rcDetailVo = new RcDetailVo();
                rcDetailVo.setTitle("可订舱位");
                rcDetailVo.setContent(content);
                rcDetailVo.setControlMode(controlMode);
                rcDetailVos.add(rcDetailVo);
            }
            intlFlightShowResponse.setPolicyDetail(rcDetailVos);
            return intlFlightShowResponse;
        }
        //低价
        RcDetailVo rcDetailVo1 = buildControlRCDetail("最低价控制");
        //提前
        RcDetailVo rcDetailVo2 = buildControlRCDetail("提前预订");
        //舱等
        RcDetailVo rcDetailVo3 = buildControlRCDetail("可订舱位");
        //提前
        RcDetailVo rcDetailVo4 = buildControlRCDetail("金额管控");
        //时间管控
        RcDetailVo rcDetailVoTime = buildControlRCDetail("时间控制");
        //协议价管控
        RcDetailVo rcDetailVoProtocolPrice = buildControlRCDetail("协议价控制");

        MbTravelstandIntlFlightVo mbTravelstandIntlFlightVo = getMbTravelstandIntlFlightVoByuidAndOrgId(uid, orgId, postId);

        // 首先判断是否有产线管控
        if (Objects.nonNull(mbTravelstandIntlFlightVo) && "N".equals(mbTravelstandIntlFlightVo.getProductSwitch())){
            rcDetailVos.add(buildAllControlRCDetail("产线管控"));
            intlFlightShowResponse.setPolicyDetail(rcDetailVos);
            return intlFlightShowResponse;
        }
        if (mbTravelstandIntlFlightVo != null) {
            if (IntlFlightSwitchEnum.LowpriceSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getLowpriceSwitch())) {
                String content = "须订" + DateUtil.dateToString(mbTravelstandIntlFlightVo.getLowpriceCompareTimeStart(),
                   DateUtil.DF_HM) + "-" + DateUtil.dateToString(mbTravelstandIntlFlightVo.getLowpriceCompareTimeEnd(),
                    DateUtil.DF_HM) + "时间段内出发时间前后" + mbTravelstandIntlFlightVo.getLowpriceTimeOption() + "分钟最低价";
                rcDetailVo1.setContent(content);
            }
            if (IntlFlightSwitchEnum.AdvancedbookSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getAdvancedbookSwitch())) {
                String content = "提前" + mbTravelstandIntlFlightVo.getAdvancedbookAdvancedDayNum() + "天预订";
                rcDetailVo2.setContent(content);
            }
            if (IntlFlightSwitchEnum.AmountControlSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getAmountControlSwitch())) {
                String content = mbTravelstandCurrencyExchangeService.showFlightAmountContext(
                     mbTravelstandIntlFlightVo.getAmountControlCurrency(), mbTravelstandIntlFlightVo.getAmountControlNum());
                rcDetailVo4.setContent(content);
            }
            if (IntlFlightSwitchEnum.ClassSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getClassSwitch())) {
                List<MbTravelstandFlightCabinVo> standFlightCabinVos = standFlightCabinService.list(
                        new MbTravelstandFlightCabinVo().setTsFlightId(mbTravelstandIntlFlightVo.getId())
                                .setTsType(TravelStandardTypeEnum.IntlFlight.getCode())
                                .setCabinType(CommonConstant.T));
                if(CollectionUtils.isNotEmpty(standFlightCabinVos)) {
                    //管控信息
                    StringBuffer content = new StringBuffer();
                    StringBuffer finalContent = content;
                    standFlightCabinVos.forEach(t->{
                        finalContent.append(IClazzEnum.getEnumByCode(t.getClassCode()).getName());
                        if(StringUtils.endsWithIgnoreCase(CommonConstant.T, t.getFlightDurationType())) {
                            finalContent.append("（飞行").append(t.getFlightDurationNum()).append("小时以上可订）");
                        }
                        finalContent.append("，");
                    });
                    if(finalContent.length()>1) {
                        content = finalContent.deleteCharAt(finalContent.length()-1);
                    }
                    rcDetailVo3.setContent(content.toString());
                } else if(StringUtils.isNotBlank(mbTravelstandIntlFlightVo.getClassClass())) {
                    IClazzEnum clazz = IClazzEnum.getEnumByCode(mbTravelstandIntlFlightVo.getClassClass());
                    String content = clazz.getName() == null ? "" : clazz.getName() + "及以下";
                    rcDetailVo3.setContent(content);
                }
            }
            //判断时间管控
            if (IntlFlightSwitchEnum.TimeSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getTimeSwitch())) {
                String split = "<br>";
                StrBuilder content = new StrBuilder();
                List<MbTravelstandIntlFlightTimeVo> mbTravelstandIntlFlightTimeVos = mbTravelstandIntlFlightTimeService.list(new MbTravelstandIntlFlightTimeVo().setTsIntlFlightId(mbTravelstandIntlFlightVo.getId()));
                for (MbTravelstandIntlFlightTimeVo mbTravelstandIntlFlightTimeVo : mbTravelstandIntlFlightTimeVos) {
                    content.append(WEEK[mbTravelstandIntlFlightTimeVo.getWeek()]);
                    content.append(" ");
                    content.append(DateUtil.dateToHM(mbTravelstandIntlFlightTimeVo.getStartTime()));
                    content.append("-");
                    content.append(DateUtil.dateToHM(mbTravelstandIntlFlightTimeVo.getEndTime()));
                    content.append("不可起飞");
                    content.append(split);
                }
                rcDetailVoTime.setContent(content.toString());
            }
            //判断协议价管控
            if (IntlFlightSwitchEnum.ProtocolPriceSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getProtocolPriceSwitch())) {
                String content = IntlFlightSwitchEnum.ProtocolPriceSwitch.getEnumByCode(mbTravelstandIntlFlightVo.getProtocolPriceSwitch()).getName();
                rcDetailVoProtocolPrice.setContent(content);
            }
            rcDetailVo1.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getLowpriceControlType()).getName());
            rcDetailVo2.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getAdvancedbookControlType()).getName());
            rcDetailVo3.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getClassControlType()).getName());
            rcDetailVo4.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getAmountControlType()).getName());
            rcDetailVoTime.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getTimeControlType()).getName());
            rcDetailVoProtocolPrice.setControlMode(ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getProtocolPriceControlType()).getName());
        }
        rcDetailVos.add(rcDetailVo1);
        rcDetailVos.add(rcDetailVo2);
        rcDetailVos.add(rcDetailVo3);
        rcDetailVos.add(rcDetailVo4);
        rcDetailVos.add(rcDetailVoTime);
        rcDetailVos.add(rcDetailVoProtocolPrice);
        intlFlightShowResponse.setPolicyDetail(rcDetailVos);
        return intlFlightShowResponse;
    }


    public IntlFlightShowResponse flightTravelStandardShowByToken(String token) {
        List<RcDetailVo> policyDetails = new ArrayList<>();
        IntlFlightShowResponse intlFlightShowResponse = new IntlFlightShowResponse();
        intlFlightShowResponse.setTitle("国际机票");
        GetTravelStandardByTokenRequest request = new GetTravelStandardByTokenRequest();
        request.setTokenList(Collections.singletonList(token));
        List<TravelStandardResponse> responseList = managementClientUtil.getTravelStandardByToken(request);
        if(CollectionUtils.isEmpty(responseList)){
            //低价
            policyDetails.add(buildControlRCDetail("最低价控制"));
            //提前
            policyDetails.add(buildControlRCDetail("提前预订"));
            //舱等
            policyDetails.add(buildControlRCDetail("可订舱位"));
            //时间管控
            policyDetails.add(buildControlRCDetail("时间控制"));
            //协议价管控
            policyDetails.add(buildControlRCDetail("协议价控制"));
            //提前
            policyDetails.add(buildControlRCDetail("金额管控"));
            intlFlightShowResponse.setPolicyDetail(policyDetails);
            return intlFlightShowResponse;
        }
        // 如果是出差申请单模式
        if(responseList.get(0).getTravelStandardToken().getOwnerType() == TravelStandardOwnerTypeEnum.TRAFFIC.getCode()){
            // 出差申请单差标优先
            policyDetails = buildFlightTravelStandardShowByApply(responseList.get(0).getRuleChain().getRuleList());
            intlFlightShowResponse.setPolicyDetail(policyDetails);
            return intlFlightShowResponse;
        }
        if(!responseList.get(0).getRuleChain().getBookable()){
            policyDetails.add(buildAllControlRCDetail("产线控制"));
            intlFlightShowResponse.setPolicyDetail(policyDetails);
            return intlFlightShowResponse;
        }
        List<TravelStandardRuleVO> ruleList = responseList.get(0).getRuleChain().getRuleList();
        if (CollectionUtils.isEmpty(ruleList)) {
            //低价
            policyDetails.add(buildControlRCDetail("最低价控制"));
            //提前
            policyDetails.add(buildControlRCDetail("提前预订"));
            //舱等
            policyDetails.add(buildControlRCDetail("可订舱位"));
            //时间管控
            policyDetails.add(buildControlRCDetail("时间控制"));
            //协议价管控
            policyDetails.add(buildControlRCDetail("协议价控制"));
            //提前
            policyDetails.add(buildControlRCDetail("金额管控"));
            intlFlightShowResponse.setPolicyDetail(policyDetails);
            return intlFlightShowResponse;
        }

        ClassDiscountRuleVO classDiscountRuleVO = (ClassDiscountRuleVO) ruleList.stream().filter(t -> "ClassDiscountRule".equals(t.getName())).findFirst().orElse(null);
        //判断折扣/舱等，填充折扣数据
        if (classDiscountRuleVO != null) {
            StringBuilder content = new StringBuilder();
            if (classDiscountRuleVO.getDiscount() == null) {
                if (CollectionUtils.isNotEmpty(classDiscountRuleVO.getClazzInfoList())) {
                    for (ClazzVo standFlightCabinVo : classDiscountRuleVO.getClazzInfoList()) {
                        content.append(ClazzEnum.getEnumByCode(standFlightCabinVo.getFlightClass())
                                .getName());
                        if (StringUtils.endsWithIgnoreCase(CommonConstant.T, standFlightCabinVo.getDurationType())) {
                            content.append("（飞行").append(standFlightCabinVo.getDurationNum()).append("小时以上可订）");
                        }
                        content.append("、");
                    }
                }
                if (content.length() > 1) {
                    content.deleteCharAt(content.length() - 1);
                }
                String controlMode = ControlTypeEnum.getEnumByCode(classDiscountRuleVO.getRejectTypes()[0]).getName();
                policyDetails.add(buildControlRCDetail("可订舱位", controlMode, content.toString()));
            }
        } else {
            policyDetails.add(buildControlRCDetail("可订舱位"));
        }

           AdvanceRuleVO advanceRuleVO = (AdvanceRuleVO) ruleList.stream().filter(t -> "AdvanceRule".equals(t.getName())).findFirst().orElse(null);
            if (advanceRuleVO != null){
                String content = "提前" + advanceRuleVO.getAdvanceDays() + "天预订";
                String controlMode = ControlTypeEnum.getEnumByCode(advanceRuleVO.getRejectTypes()[0]).getName();
                policyDetails.add(buildControlRCDetail("最低价控制", controlMode, content));
            } else {
                policyDetails.add(buildControlRCDetail("最低价控制"));
            }
        LowPriceRuleVO lowPriceRuleVO = (LowPriceRuleVO) ruleList.stream().filter(t -> "LowPriceRule".equals(t.getName())).findFirst().orElse(null);
        if (lowPriceRuleVO != null){
            String content = "须订" + lowPriceRuleVO.getPriceStartTime()+ "-" + lowPriceRuleVO.getPriceEndTime() + "时间段内出发时间前后" + lowPriceRuleVO.getCompareInMinutes() + "分钟最低价";
            String controlMode = ControlTypeEnum.getEnumByCode(lowPriceRuleVO.getRejectTypes()[0]).getName();
            policyDetails.add(buildControlRCDetail("提前预订", controlMode, content));
        } else {
            policyDetails.add(buildControlRCDetail("提前预订"));
        }
        List<ForbidTimeRuleVO> forbidTimeRuleVOList = ruleList.stream()
                .filter(t -> "ForbidTimeRule".equals(t.getName()))
                .map(t-> (ForbidTimeRuleVO)t)
                .collect(Collectors.toList());
        //判断时间管控
        if (CollectionUtils.isNotEmpty(forbidTimeRuleVOList)) {
            String split = "<br>";
            StrBuilder content = new StrBuilder();
            for (ForbidTimeRuleVO mbTravelstandFlightTimeVo : forbidTimeRuleVOList) {
                content.append(WEEK[mbTravelstandFlightTimeVo.getWeekDay()]);
                content.append(" ");
                content.append(mbTravelstandFlightTimeVo.getStartTime());
                content.append("-");
                content.append(mbTravelstandFlightTimeVo.getEndTime());
                content.append("不可起飞");
                content.append(split);
            }
            policyDetails.add(buildControlRCDetail("时间控制", ControlTypeEnum.getEnumByCode(forbidTimeRuleVOList.get(0).getRejectTypes()[0]).getName(), content.toString()));
        }else {
            policyDetails.add(buildControlRCDetail("时间控制"));
        }

        AmountRuleVO amountRuleVO = (AmountRuleVO) ruleList.stream().filter(t -> "AmountRule".equals(t.getName())).findFirst().orElse(null);
        //判断金额管控
        if (amountRuleVO != null) {
            String content = showFlightAmountContext(CNY_CODE, amountRuleVO.getAmountControlNum());
            String controlMode = ControlTypeEnum.getEnumByCode(amountRuleVO.getRejectTypes()[0]).getName();
            policyDetails.add(buildControlRCDetail("金额管控", controlMode, content));
        } else {
            policyDetails.add(buildControlRCDetail("金额管控"));
        }

        ProtocolPriceRuleVO protocolPriceRuleVO = (ProtocolPriceRuleVO) ruleList.stream().filter(t -> "ProtocolPriceRule".equals(t.getName())).findFirst().orElse(null);
        //判断协议价管控
        if (protocolPriceRuleVO != null) {
            String content = FlightSwitchEnum.ProtocolPriceSwitch.E.getName();
            String controlMode = ControlTypeEnum.getEnumByCode(protocolPriceRuleVO.getRejectTypes()[0]).getName();
            policyDetails.add(buildControlRCDetail("协议价控制", controlMode, content));
        } else {
            policyDetails.add(buildControlRCDetail("协议价控制"));
        }

        intlFlightShowResponse.setPolicyDetail(policyDetails);
        return intlFlightShowResponse;
    }
    /**
     * 根据出差申请单差标构建APP端机票差标展示
     */
    private List<RcDetailVo> buildFlightTravelStandardShowByApply(List<TravelStandardRuleVO> ruleList) {
        List<RcDetailVo> policyDetails = new ArrayList<>();
        PriceRuleVO priceRuleVO = (PriceRuleVO) ruleList.stream().filter(t -> "PriceRule".equals(t.getName())).findFirst().orElse(null);
        ReserveRuleVO reserveRuleVO = (ReserveRuleVO) ruleList.stream().filter(t -> "ReserveRule".equals(t.getName())).findFirst().orElse(null);
        // 可订舱位不限
        if (reserveRuleVO != null && CollectionUtils.isEmpty(reserveRuleVO.getReserves())) {
            policyDetails.add(buildControlRCDetail("可订舱位"));
        } else {
            String content = reserveRuleVO.getReserves().entrySet().stream()
                    .map(Map.Entry::getKey)
                    .map(CabinFlag::valueOf)
                    .map(CabinFlag::getDisplayName)
                    .collect(Collectors.joining("、"));
            String controlMode = ControlTypeEnum.getEnumByCode(reserveRuleVO.getRejectTypes()[0]).getName();
            RcDetailVo rcDetailVo = new RcDetailVo();
            rcDetailVo.setTitle("可订舱位");
            rcDetailVo.setContent(content);
            rcDetailVo.setControlMode(controlMode);
            policyDetails.add(rcDetailVo);
        }
        // 出差申请单差标优先
        policyDetails.add(buildControlRCDetail("最低价控制"));
        policyDetails.add(buildControlRCDetail("提前预订"));
        return policyDetails;
    }

    public String showFlightAmountContext(String currencyCode, Integer amountNum) {
        if (CNY_CODE.equals(currencyCode)) {
            return "金额管控价格上限" + CNY_SYMBOL + amountNum;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("金额管控价格上限").append(currencyCode).append(" ").append(amountNum);
        CurrencyExchangeBO currencyExchangeBO = CurrencyConversionUtil.exchangeCurrency(currencyCode, CNY_CODE, new BigDecimal(amountNum));
        if (!Objects.isNull(currencyExchangeBO)) {
            sb.append("(等价人民币为").append(CNY_SYMBOL).append(currencyExchangeBO.getToCurrencyAmount().toString()).append(")");
            log.info("汇率转换前币种为{}，金额为{}，转换后未四舍五入的金额为¥{}，当前token为{}", currencyCode, amountNum,
                    currencyExchangeBO.getToCurrencyAmount().toString(), currencyExchangeBO.getExchangeToken());
        }
        return sb.toString();
    }
    private RcDetailVo buildControlRCDetail(String title){
        RcDetailVo rcDetailVo3 = new RcDetailVo();
        rcDetailVo3.setTitle(title);
        rcDetailVo3.setContent("不限");
        rcDetailVo3.setControlMode("不管控");
        return rcDetailVo3;
    }

    private RcDetailVo buildControlRCDetail(String title, String controlMode, String content){
        RcDetailVo rcDetailVo3 = new RcDetailVo();
        rcDetailVo3.setTitle(title);
        rcDetailVo3.setContent(content);
        rcDetailVo3.setControlMode(controlMode);
        return rcDetailVo3;
    }

    private RcDetailVo buildAllControlRCDetail(String title){
        RcDetailVo rcDetailVo3 = new RcDetailVo();
        rcDetailVo3.setTitle(title);
        rcDetailVo3.setContent("禁止预订");
        rcDetailVo3.setControlMode("禁止预订");
        return rcDetailVo3;
    }

    /**
     * 将MbTravelstandIntlFlightVo转换为IntlFlightOperateLogVo
     */
    private IntlFlightOperateLogVo coverMbTravelstandIntlFlightVoToIntlFlightOperateLogVo(MbTravelstandIntlFlightVo mbTravelstandIntlFlightVo) {
        if (mbTravelstandIntlFlightVo != null) {
            IntlFlightOperateLogVo intlFlightOperateLogVo = new IntlFlightOperateLogVo();
            intlFlightOperateLogVo.setName(mbTravelstandIntlFlightVo.getName());
            //设置职级范围
            List<String> jobNames = travelStandardPostService.getJobNamesByTsIdAndTsType(mbTravelstandIntlFlightVo.getId(), TravelStandardTypeEnum.IntlFlight.getCode());
            StringBuilder jobScope = new StringBuilder();
            for (String jobName : jobNames) {
                jobScope.append(jobName);
                jobScope.append(",");
            }
            if (jobNames.size() > 0) {
                jobScope.deleteCharAt(jobScope.length() - 1);
            }
            intlFlightOperateLogVo.setJobScope(jobScope.toString());
            //设置舱等信息
            IntlFlightSwitchEnum.ClassSwitch classSwitch = IntlFlightSwitchEnum.ClassSwitch.getEnumByCode(mbTravelstandIntlFlightVo.getClassSwitch());
            intlFlightOperateLogVo.setClassSwitch(classSwitch == null ? "" : classSwitch.getName());
            StringBuilder classInfo = new StringBuilder();
            IClazzEnum clazzEnum = IClazzEnum.getEnumByCode(mbTravelstandIntlFlightVo.getClassClass());
            classInfo.append(clazzEnum == null ? "" : clazzEnum.getName());
            intlFlightOperateLogVo.setClassInfo(classInfo.toString());

            //设置低价信息
            FlightSwitchEnum.LowpriceSwitch lowpriceSwitch = FlightSwitchEnum.LowpriceSwitch.getEnumByCode(mbTravelstandIntlFlightVo.getLowpriceSwitch());
            intlFlightOperateLogVo.setLowpriceSwitch(lowpriceSwitch == null ? null : lowpriceSwitch.getName());
            intlFlightOperateLogVo.setLowpriceTimeOptionHour(mbTravelstandIntlFlightVo.getLowpriceTimeOption() == null ? null : String.valueOf(mbTravelstandIntlFlightVo.getLowpriceTimeOption() / 60));
            intlFlightOperateLogVo.setLowpriceTimeOptionMinute(mbTravelstandIntlFlightVo.getLowpriceTimeOption() == null ? null : String.valueOf(mbTravelstandIntlFlightVo.getLowpriceTimeOption() % 60));
            intlFlightOperateLogVo.setLowpriceCompareTimeStart(mbTravelstandIntlFlightVo.getLowpriceCompareTimeStart() == null ? null : DateUtil.dateToString(mbTravelstandIntlFlightVo.getLowpriceCompareTimeStart(), DateUtil.DF_HM));
            intlFlightOperateLogVo.setLowpriceCompareTimeEnd(intlFlightOperateLogVo.getLowpriceCompareTimeEnd() == null ? null : DateUtil.dateToString(mbTravelstandIntlFlightVo.getLowpriceCompareTimeEnd(), DateUtil.DF_HM));

            intlFlightOperateLogVo.setLowpriceFloatType(mbTravelstandIntlFlightVo.getLowpriceFloatType());
            intlFlightOperateLogVo.setLowpriceFloatAmount(mbTravelstandIntlFlightVo.getLowpriceFloatAmount() == null ? "0" :
                    mbTravelstandIntlFlightVo.getLowpriceFloatAmount().toString());
            intlFlightOperateLogVo.setLowpriceFloatNum(mbTravelstandIntlFlightVo.getLowpriceFloatNum() == null ? "0" :
                    mbTravelstandIntlFlightVo.getLowpriceFloatNum().toString());

            //设置协议价信息
            FlightSwitchEnum.ProtocolPriceSwitch protocolPriceSwitch = FlightSwitchEnum.ProtocolPriceSwitch.getEnumByCode(mbTravelstandIntlFlightVo.getProtocolPriceSwitch());
            intlFlightOperateLogVo.setProtocolPriceSwitch(Objects.isNull(protocolPriceSwitch) ? null : protocolPriceSwitch.getName());

            //舱等超标管控原因
            ControlTypeEnum classControlType = ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getClassControlType());
            intlFlightOperateLogVo.setClassControlType(classControlType == null ? "" : classControlType.getName());
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getClassControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandIntlFlightVo.getId());
                    setTsRcType(ReasonCodeTypeEnum.IFC.getCode());
                }});
                intlFlightOperateLogVo.setClassControlRcs(appendRcs(mbTravelstandReasonCodeVos));
            }
            //低价管控原因
            ControlTypeEnum lowpriceControlType = ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getLowpriceControlType());
            intlFlightOperateLogVo.setLowpriceControlType(lowpriceControlType == null ? null : lowpriceControlType.getName());
            intlFlightOperateLogVo.setAirportComparePrice(mbTravelstandIntlFlightVo.getAirportComparePrice());
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getLowpriceControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandIntlFlightVo.getId());
                    setTsRcType(ReasonCodeTypeEnum.IFL.getCode());
                }});
                intlFlightOperateLogVo.setLowpriceControlRcs(appendRcs(mbTravelstandReasonCodeVos));
            }
            //协议价超标管控原因
            ControlTypeEnum protocolPriceControlType = ControlTypeEnum.getEnumByCode(mbTravelstandIntlFlightVo.getProtocolPriceControlType());
            intlFlightOperateLogVo.setProtocolPriceControlType(Objects.isNull(protocolPriceControlType)? null : protocolPriceControlType.getName());
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getProtocolPriceControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandIntlFlightVo.getId());
                    setTsRcType(ReasonCodeTypeEnum.IFP.getCode());
                }});
                intlFlightOperateLogVo.setProtocolPriceControlRcs(appendRcs(mbTravelstandReasonCodeVos));
            }

            return intlFlightOperateLogVo;
        }
        return null;
    }

    private String appendRcs(List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos) {
        StringBuilder classDiscountControlRcs = new StringBuilder();
        for (MbTravelstandReasonCodeVo codeVo : mbTravelstandReasonCodeVos) {
            classDiscountControlRcs.append(codeVo.getName());
            classDiscountControlRcs.append(",");
        }
        if (mbTravelstandReasonCodeVos.size() > 0) {
            classDiscountControlRcs.deleteCharAt(classDiscountControlRcs.length() - 1);
        }
        return classDiscountControlRcs.toString();
    }

    @Autowired
    private IPostService postService;

    /**
     * 根据uid和orgId获得对应国际机票差标
     *
     * @param uid
     * @param orgId 组织id，对应的组织类型可能是公司、部门。
     *              用于从mb_user_org_relation表中拿到对应的职级id
     * @return
     */
    public MbTravelstandIntlFlightVo getMbTravelstandIntlFlightVoByuidAndOrgId(String uid, String orgId, Long postId) {

        if (Objects.nonNull(postId) && postId > 0){

        } else {
            if (StringUtils.isBlank(uid)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_IS_NULL);
            }
            if (StringUtils.isBlank(orgId)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
            }
            //根据uid和orgId查到对应职位
            PostVo postVo = postService.listPostByUidAndOrgId(uid, orgId);
            //判断岗位是否存在
            if (postVo == null) {
                return null;
            }
            postId = postVo.getId();
        }

        //根据职位查找对应机票差标
        TravelStandardPostVo vo = new TravelStandardPostVo();
        vo.setPostid(postId);
        vo.setTstype(TravelStandardTypeEnum.IntlFlight.getCode());
        List<TravelStandardPost> travelStandardPostVos = standPostService.list(vo);
        if (travelStandardPostVos == null || travelStandardPostVos.size() == 0) {
            return null;
        }
        //获取对应差标
        return get(travelStandardPostVos.get(0).getTsid());
    }

	public IntlFlightShowResponse intlFlightShow(IntlFlightShowRequest request) {
		UserInfo userInfo = request.getUserInfo();
		String policyOrgId = request.getPolicyOrgId();
		String policyId = request.getPolicyId();
		if (StringUtils.isBlank(policyOrgId) && StringUtils.isBlank(policyId)){
			policyId = userInfo.getUid();
			policyOrgId = userInfo.getOrgId();
		}
        return this.intlFlightShow(policyOrgId, policyId, request.getPostId(), request.getTrafficId(), request.getToken());
	}

	public FlightIntlTravelStandardShowTextResponse flightIntlTravelStandardShowText(TravelStandardSoaRequestVo request) {
        FlightIntlTravelStandardShowTextResponse response = new FlightIntlTravelStandardShowTextResponse();
        MbTravelstandIntlFlightVo mbTravelstandIntlFlightVo = getMbTravelstandIntlFlightVoByuidAndOrgId(request.getUserId(), request.getOrgId(), null);
        if (Objects.isNull(mbTravelstandIntlFlightVo)) {
            return null;
        }
        if ("N".equals(mbTravelstandIntlFlightVo.getProductSwitch())){
            String controlInfo = "产线管控：禁止预订";
            response.setControlInfos(Collections.singletonList(controlInfo));
            return response;
        }
        //管控信息
        List<String> controlInfos = new ArrayList<>();
        //超标原因
        List<String> controlRcInfos = new ArrayList<>();
        //设置舱等/折扣
        boolean classDiscountRcFlag = false;
        if (FlightSwitchEnum.ClassSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getClassSwitch())) {
            List<MbTravelstandFlightCabinVo> standFlightCabinVos = standFlightCabinService.list(
                    new MbTravelstandFlightCabinVo().setTsFlightId(mbTravelstandIntlFlightVo.getId())
                            .setTsType(TravelStandardTypeEnum.IntlFlight.getCode())
                            .setCabinType(CommonConstant.T));
            if(CollectionUtils.isNotEmpty(standFlightCabinVos)) {
                standFlightCabinVos.forEach(t->{
                    StringBuffer content = new StringBuffer(IClazzEnum.getEnumByCode(t.getClassCode()).getName());
                    if(StringUtils.endsWithIgnoreCase(CommonConstant.T, t.getFlightDurationType())) {
                        content.append("（飞行").append(t.getFlightDurationNum()).append("小时以上可订）");
                    }
                    controlInfos.add(content.toString());
                });
            } else if(StringUtils.isNotBlank(mbTravelstandIntlFlightVo.getClassClass())) {
                List<IClazzEnum> clazzEnums = IClazzEnum.getLowerClazzEnumThanCode(mbTravelstandIntlFlightVo.getClassClass());
                for (IClazzEnum clazzEnum : clazzEnums) {
                    controlInfos.add(clazzEnum.getName());
                }
            }
            classDiscountRcFlag = true;
        }
        if (classDiscountRcFlag) {
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getClassControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(
                        new MbTravelstandReasonCodeVo()
                                .setTsId(mbTravelstandIntlFlightVo.getId())
                                .setTsRcType(ReasonCodeTypeEnum.FC.getCode())
                                .setIsChecked(true)
                );
                for (MbTravelstandReasonCodeVo mbTravelstandReasonCodeVo : mbTravelstandReasonCodeVos) {
                    controlRcInfos.add(mbTravelstandReasonCodeVo.getName());
                }
            }
        }
        //设置低价
        if (FlightSwitchEnum.LowpriceSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getLowpriceSwitch())) {
            controlInfos.add("最低价");
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getLowpriceControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(
                        new MbTravelstandReasonCodeVo()
                                .setTsId(mbTravelstandIntlFlightVo.getId())
                                .setTsRcType(ReasonCodeTypeEnum.FL.getCode())
                                .setIsChecked(true)
                );
                for (MbTravelstandReasonCodeVo mbTravelstandReasonCodeVo : mbTravelstandReasonCodeVos) {
                    controlRcInfos.add(mbTravelstandReasonCodeVo.getName());
                }
            }
        }
        //设置提前预订
        if (FlightSwitchEnum.AdvancedbookSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getAdvancedbookSwitch())) {
            controlInfos.add("提前" + mbTravelstandIntlFlightVo.getAdvancedbookAdvancedDayNum() + "天");
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getAdvancedbookControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(
                        new MbTravelstandReasonCodeVo()
                                .setTsId(mbTravelstandIntlFlightVo.getId())
                                .setTsRcType(ReasonCodeTypeEnum.FA.getCode())
                                .setIsChecked(true)
                );
                for (MbTravelstandReasonCodeVo mbTravelstandReasonCodeVo : mbTravelstandReasonCodeVos) {
                    controlRcInfos.add(mbTravelstandReasonCodeVo.getName());
                }
            }
        }
        //金额管控
        if (FlightSwitchEnum.AmountControlSwitch.E.getCode().equals(mbTravelstandIntlFlightVo.getAmountControlSwitch())) {
            controlInfos.add(mbTravelstandCurrencyExchangeService.showFlightAmountContext(
               mbTravelstandIntlFlightVo.getAmountControlCurrency(), mbTravelstandIntlFlightVo.getAmountControlNum()));
            if (ControlTypeEnum.C.getCode().equals(mbTravelstandIntlFlightVo.getAmountControlType())) {
                List<MbTravelstandReasonCodeVo> mbTravelstandReasonCodeVos = travelstandReasonCodeService.list(
                        new MbTravelstandReasonCodeVo()
                                .setTsId(mbTravelstandIntlFlightVo.getId())
                                .setTsRcType(ReasonCodeTypeEnum.IAM.getCode())
                                .setIsChecked(true)
                );
                for (MbTravelstandReasonCodeVo mbTravelstandReasonCodeVo : mbTravelstandReasonCodeVos) {
                    controlRcInfos.add(mbTravelstandReasonCodeVo.getName());
                }
            }
        }
        response.setControlInfos(controlInfos);
        response.setControlRcInfos(controlRcInfos);
        return response;
    }
}
